#ifndef __PONG3D_H__
#define __PONG3D_H__

#include "Structs.h"
#include <GL/glut.h>


#define NUM_PLAYERS 2
#define WORLD_WIDTH 16
#define WORLD_HEIGHT 10
#define MAX_BALLS 10
#define NEAR_PLANE 7
#define FAR_PLANE -7
#define MAX_POINTS 10
#define true 1
#define false 0
#define __debug 0



//Functions Pong3D.c
/*
Function Name: Passive Motion
Description: Controls the inputs via the mouse movement, or wiimote movement
Inputs: X and Y Screen coordinates
returns: void
*/
void passiveMotion(int x, int y); //WII or MOUSE input
/*
Function Name: Lighting
Description: Sets the lighting parameters for the game
Inputs: void
returns: void
*/
void lighting (void);
/*
Function Name: drawPaddles
Description: Draws the paddles based upon the given position (GLOBAL)
Inputs: void
returns: void
*/
void drawPaddles(void);
/*
Function Name: drawScore
Description: Renders the players score on the screen
Inputs: void
returns: void
*/
void drawScore(void);
/*
Function Name: changeState
Description: Manages the state transitions and logic required within
Inputs: The new state
returns: void
*/
void changeState(enum State newState);
/*
Function Name: setPerspective
Description: Sets the frustrum via the gluPerspective method, this provides
a wrapper to maintain consistent perspective
Inputs: void
returns: void
*/
void setPerspective();
/*
Function Name: updateAI
Description: determines the new positions of the AI paddle
Inputs: void
returns: void
*/
void updateAI();
/*
Function Name: VictoryScreen
Description: Displays the win/loss screen upon game completion
Inputs: void
returns: void
*/
void victoryScreen();
/*
Function Name: keyboard 
Description: Callback for glu keyboard inputs
Inputs: the key pressed
returns: void
*/
void keyboard(unsigned char key, int x, int y);
/*
Function Name: floatRand
Description: returns a random float with the given maximum value
Inputs: the maximum value
returns: void
*/
float floatRand(float max);

//Tools.c
/*
Function Name:raw_texture_load
Description: Loads a row texture from a file
Inputs: the filename and dimensions of th file
returns: GLuint of the texture refrence
*/
GLuint raw_texture_load(const char *filename, int width, int height);
/*
Function Name:gltLoadTGA
Description: Loads TGA files
Inputs: the filename, dimensions and the components of the file.
returns: GLbyte refrencing the given texture
*/
GLbyte *gltLoadTGA(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat);
/*
Function Name: copyArray
Description: Copys array b to array a
Inputs: Array A and B
returns: void
*/
void copyArray(GLfloat *a, GLfloat *b, int size);
/*
Function Name: draw Text
Description: Renders text on the screen
Inputs: The string to render, and the position
returns: void
*/
void drawText(char * str, GLfloat xPos, GLfloat yPos, GLfloat zPos);

//Ball.c 
/*
Function Name: checkCollisions
Description: Determines collisions between the ball and all other game objects
Inputs: void
returns: void
*/
void checkCollisions();
/*
Function Name:drawBalls
Description: Renders all of the balls which are inplay
Inputs: void
returns: void
*/
void drawBalls(void);
/*
Function Name:initBalls
Description: initializes the balls, sets vectors, speed, position etc
Inputs: void
returns: void
*/
void initballs();
/*
Function Name: drawBall
Description: Draws the ball with a specific texture and size
Inputs: GLUquadricObj of spehere, a radius, and a texture
returns: void
*/
void drawBall(GLUquadricObj *sphere, GLfloat radius, GLuint textureName);

//Skybox.c
/*
Function Name: loadSkyBox
Description: Loads the images associated with the skybox
Inputs: 
returns: 
*/
void loadSkyBox(void);
/*
Function Name: drawSkyBox
Description: renders the skybox outside of the scene
Inputs: 
returns: 
*/
void drawSkybox(void);

//Walls.c
/*
Function Name: drawWalls
Description: renders the walls of the scene
Inputs: 
returns: 
*/
void drawWalls(void);

/*
Function Name: defineWalls
Description: initializes the walls of the scene based upon the screen size
Inputs: 
returns: 
*/
void defineWalls();

//Hud.c
/*
Function Name: drawScore
Description: Draws the score of the screen ontop of the scene
Inputs: 
returns: 
*/
void drawScore(void);

//PickTexture.c
/*
Function Name: pickObject
Description: Detemines which object is picked in the scene
Inputs: x and y screen coodrinates
returns: GLuint of picked object
*/
GLuint pickObject(int x, int y);	
/*
Function Name: drawPickObjects
Description: Draws the objects included in the pick list
Inputs: 
returns: 
*/
void drawPickObjects();

//AI
/*
Function Name: getAIPaddlePosition
Description: Calculates the ai's position based upon the ball position
Inputs: 
returns: 
*/
void getAIPaddlePosition(GLfloat *aiPos, GLfloat paddleX, GLfloat paddleY, GLfloat paddleZ, 
								GLfloat ballX, GLfloat ballY, GLfloat ballZ, 
								GLfloat maxSpeed, GLfloat tolerance);

//ModelLoader.c
/*
Function Name:drawVictoryPaddle
Description:  draws the paddles in the final scene
Inputs: 
returns: 
*/
void drawVictoryPaddle();
/*
Function Name:drawTrophy
Description:  draws the trophy in the final scene
Inputs: 
returns: 
*/
void drawTrophy();
/*
Function Name:drawSkulll
Description:  draws the skull in the final scene
Inputs: 
returns: 
*/
void drawSkull();

//Wiimote
#ifdef __WII__
/*
Function Name: connect_wii
Description: HAndles connecting all wii motes to the PC system and initialising all relevant variables 
Inputs: null
returns:	number of wii motes connected
*/
int connect_wii();
/*
Function Name:
Description: 
Inputs: 
returns: 
*/
void poll_wii();
#endif

int width;
int height;
float fAspect;

//Walls
struct Wall leftWall;
struct Wall rightWall;
struct Wall topWall;
struct Wall bottomWall;

//Light sources
extern GLfloat whiteSpecularLight[]; 
extern GLfloat paleAmbientLight[];
extern GLfloat blackAmbientLight[];
extern GLfloat whiteDiffuseLight[];

//Colors
extern GLfloat COLOR_WHITE[];
extern GLfloat COLOR_BLACK[];
extern GLfloat COLOR_RED[];
extern GLfloat COLOR_BLUE[];
extern GLfloat COLOR_GREEN[];
extern GLfloat COLOR_YELLOW[];
extern GLfloat COLOR_NEON_PINK[];
extern GLfloat COLOR_GOLD[];
extern GLfloat COLOR_BLACK_50[];
extern GLfloat COLOR_RED_50[];
extern GLfloat COLOR_BLUE_50[];
extern GLfloat COLOR_GREEN_50[];
extern GLfloat COLOR_YELLOW_50[];
extern GLfloat COLOR_NEON_PINK_50[];


static int win;


struct Player _players[NUM_PLAYERS];
struct Paddle _paddles[NUM_PLAYERS];
struct Ball _balls[MAX_BALLS];

//Paddles and players
extern GLfloat playerColors[][4];
extern GLfloat paddlePosition[][3];
extern enum InputDevice _inputDevice[];


extern GLfloat paddleDeltaVec[];
extern enum State _lastState;
extern enum State _state;
extern int _ballsInPlay;


GLuint _skyBox[6];
#define paddleXRadius 2
#define paddleYRadius 1
extern GLfloat paddleDimensions[][3];
//GLfloat paddleXRadius = 3.0f;

extern GLfloat centerPoint[];
extern GLfloat fov;

extern GLfloat _aspect;
extern GLfloat _debugRotate;

extern GLint _trophyAngle; 
#endif